package com.ruoyi.coal.modules.publicAPI.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itextpdf.text.pdf.AcroFields;
import com.ruoyi.coal.common.exception.RRException;
import com.ruoyi.coal.common.utils.R;
import com.ruoyi.coal.common.utils.WordUtils;
import com.ruoyi.coal.modules.coalpile.domain.CoalPileInfoEntity;
import com.ruoyi.coal.modules.coalpile.domain.CoalYardHistoryEntity;
import com.ruoyi.coal.modules.coalpile.domain.CoalYardInfoEntity;
import com.ruoyi.coal.modules.coalpile.domain.CutUpEntity;
import com.ruoyi.coal.modules.coalpile.domain.vo.CoalPileInfoVo;
import com.ruoyi.coal.modules.coalpile.domain.vo.PdfVo;
import com.ruoyi.coal.modules.coalpile.mapper.CoalYardHistoryDao;
import com.ruoyi.coal.modules.coalpile.service.CoalPileInfoService;
import com.ruoyi.coal.modules.coalpile.service.CoalYardInfoService;
import com.ruoyi.coal.modules.coalpile.service.CutUpService;
import com.ruoyi.coal.modules.minio.MinioConfig;
import com.ruoyi.coal.modules.publicAPI.service.PublicService;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import com.spire.xls.FileFormat;
import com.spire.xls.Workbook;
import io.minio.errors.ErrorResponseException;
import io.minio.errors.InsufficientDataException;
import io.minio.errors.InternalException;
import io.minio.errors.InvalidArgumentException;
import io.minio.errors.InvalidBucketNameException;
import io.minio.errors.InvalidResponseException;
import io.minio.errors.NoResponseException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.xmlpull.v1.XmlPullParserException;

@Api(value = "publicInfo", tags = {"公开接口"})
@RestController
@RequestMapping({"public"})
@DataSource(value = DataSourceType.SLAVE)
public class PublicController {
    private static final Logger log = LoggerFactory.getLogger(com.ruoyi.coal.modules.publicAPI.controller.PublicController.class);

    @Autowired
    private CoalPileInfoService coalPileInfoService;

    @Autowired
    private CoalYardInfoService coalYardInfoService;

    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private CutUpService cutUpService;

    @Autowired
    private CoalYardHistoryDao coalYardHistoryDao;

    @Value("${minio.filederName}")
    private String filederName;

    @Autowired
    private PublicService publicService;

    @ApiOperation("上传文件")
    @PostMapping({"/uploadCloud"})
    public R upload(@RequestBody MultipartFile file, @RequestParam("id") Integer id) throws IOException, InvalidKeyException, NoSuchAlgorithmException, XmlPullParserException, InvalidArgumentException, InvalidResponseException, ErrorResponseException, NoResponseException, InvalidBucketNameException, InsufficientDataException, InternalException {
        String yyyyMMddHHmmss = DateUtil.format(new Date(), "yyyy-MM-dd-HH-mm-ss");
        String upload = this.minioConfig.upload(file, "importasc", yyyyMMddHHmmss);
        Map<String, Object> stringObjectMap = this.publicService.delDataAndGetMaxMin(id, upload);
        stringObjectMap.put("asc_url", upload);
        return R.ok().put("data", stringObjectMap);
    }

    @ApiOperation("根据文件夹名称上传文件")
    @PostMapping({"/uploadCloudByFile"})
    public R uploadByFile(@RequestParam("id") Integer id) throws IOException, InvalidKeyException, NoSuchAlgorithmException, XmlPullParserException, InvalidArgumentException, InvalidResponseException, ErrorResponseException, NoResponseException, InvalidBucketNameException, InsufficientDataException, InternalException {
        String yyyyMMddHHmmss = DateUtil.format(new Date(), "yyyy-MM-dd-HH-mm-ss");
        int i = this.coalYardInfoService.filecount();
        if (i != 0) {
            File file = this.coalYardInfoService.getALLFile(this.filederName);
            if (file.length() != 0L) {
                InputStream inputStream = new FileInputStream(file);
                MockMultipartFile mockMultipartFile = new MockMultipartFile(file.getName(), inputStream);
                String upload = this.minioConfig.upload((MultipartFile) mockMultipartFile, "importasc", yyyyMMddHHmmss);
                this.coalYardInfoService.removeFile(this.filederName);
                Map<String, Object> stringObjectMap = this.publicService.delDataAndGetMaxMin(id, upload);
                stringObjectMap.put("asc_url", upload);
                return R.ok().put("data", stringObjectMap);
            }
        }
        return R.error("上传的文件为空");
    }

    @ApiOperation("生成总的pdf")
    @GetMapping({"/pdf"})
    public String pdf(@RequestParam("CoalYardId") Integer CoalYardId, @RequestParam("historyId") Integer historyId) {
        this.publicService.writeToExcel(CoalYardId, historyId);
        Workbook wb = new Workbook();
        wb.loadFromFile("./xmsy2.xlsx");
        wb.getConverterSetting().setSheetFitToPage(true);
        wb.saveToFile("ToPDF.pdf", FileFormat.PDF);
        File file = new File("./ToPDF.pdf");
        FileInputStream input = null;
        MultipartFile mockMultipartFile = null;
        String result = null;
        try {
            CoalYardHistoryEntity coalYardHistoryEntity = (CoalYardHistoryEntity) this.coalYardHistoryDao.selectById(historyId);
            input = new FileInputStream(file);
            MockMultipartFile mockMultipartFile1 = new MockMultipartFile("file", file.getName(), "application/octet-stream", IOUtils.toByteArray(input));
            result = this.minioConfig.upload((MultipartFile) mockMultipartFile1, "pdf", DateUtil.format(coalYardHistoryEntity.getTime(), "yyyy-MM-dd-HH-mm-ss") + "_" + coalYardHistoryEntity.getCoalYardId());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @ApiOperation("生成Excels")
    @GetMapping({"/excels"})
    public String excels(@RequestParam("CoalYardId") Integer CoalYardId, @RequestParam("historyId") Integer historyId) {
        this.publicService.writeToExcel(CoalYardId, historyId);
        File file = new File("./xmsy2.xlsx");
        FileInputStream input = null;
        MultipartFile mockMultipartFile = null;
        String result = null;
        try {
            CoalYardHistoryEntity coalYardHistoryEntity = (CoalYardHistoryEntity) this.coalYardHistoryDao.selectById(historyId);
            input = new FileInputStream(file);
            MockMultipartFile mockMultipartFile1 = new MockMultipartFile("file", file.getName(), "application/octet-stream", IOUtils.toByteArray(input));
            result = this.minioConfig.upload((MultipartFile) mockMultipartFile1, "xlsx", DateUtil.format(coalYardHistoryEntity.getTime(), "yyyy-MM-dd-HH-mm-ss") + "_" + coalYardHistoryEntity.getCoalYardId());
        } catch(Exception e){
            e.printStackTrace();
        }
        return result;
    }

    @ApiOperation(value = "生成报表文件(模版法)", notes = "生成报表文件(模版法)")
    @GetMapping({"/getTempPDF/{CoalPileId}"})
    public void generateTempPDF(@PathVariable("CoalPileId") String CoalPileId, HttpServletResponse response) throws Exception {
        PdfVo data = this.coalPileInfoService.getPdfVoByPileId(Integer.parseInt(CoalPileId));
        if (data == null) {
            response.sendError(404, "该煤堆不存在");
            log.error("生成pdf失败,{}该煤堆不存在", CoalPileId);
            return;
        }
        CutUpEntity cutUp = this.cutUpService.getCutUpByCutUpId(data.getCoalPileInfoEntity().getCutId());
        data.getCoalPileInfoEntity().setCoalPileVariety(cutUp.getCoalPileVariety());
        ByteArrayOutputStream outputStream = WordUtils.generatePdf(data);
        Date createTime = data.getCoalPileInfoEntity().getCreateTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd HH:mm");
        String datetime = simpleDateFormat.format(createTime);
        String cutNameUTF = URLEncoder.encode(cutUp.getName(), "UTF-8");
        response.setHeader("Content-type", "application/pdf");
        response.setHeader("Content-Disposition", "attachement;filename=" + datetime + cutNameUTF + ".pdf");
        InputStream is = new ByteArrayInputStream(outputStream.toByteArray());
        IOUtils.copy(is, (OutputStream) response.getOutputStream());
        response.flushBuffer();
    }

    @ApiOperation(value = "生成煤堆word", notes = "生成煤堆word")
    @GetMapping({"/getCoalPileWord/{CoalPileId}"})
    public void getCoalPileWord(@PathVariable("CoalPileId") String CoalPileId, HttpServletResponse response) throws Exception {
        Map<String, Object> data = new HashMap<>();
        Map<String, Object> picData = new HashMap<>();
        PdfVo pdfVo = this.coalPileInfoService.getPdfVoByPileId(Integer.parseInt(CoalPileId));
        if (pdfVo == null) {
            response.sendError(404, "该煤堆不存在");
            log.error("生成word失败,{}该煤堆不存在", CoalPileId);
            return;
        }
        CoalYardHistoryEntity historyEntity = (CoalYardHistoryEntity) this.coalYardHistoryDao.selectById(pdfVo.getCoalPileInfoEntity().getHistoryId());
        Integer coalYardId = ((CoalYardInfoEntity) this.coalYardInfoService.getById(historyEntity.getCoalYardId())).getId();
        Date createTime = pdfVo.getCoalPileInfoEntity().getCreateTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String datetime = simpleDateFormat.format(createTime);
        data.put("${1}", pdfVo.getCoalPileInfoEntity().getName());
        data.put("${2}", datetime);
        data.put("${3}", pdfVo.getCoalPileInfoEntity().getVolume());
        data.put("${4}", pdfVo.getCoalPileInfoEntity().getDensity());
        data.put("${5}", pdfVo.getCoalPileInfoEntity().getWeight());
        data.put("${6}", pdfVo.getCoalPileInfoEntity().getLength());
        data.put("${7}", pdfVo.getCoalPileInfoEntity().getWidth());
        data.put("${8}", pdfVo.getCoalPileInfoEntity().getHeight());
        if (StringUtils.isEmpty(this.cutUpService.getCutUpByCutUpId(pdfVo.getCoalPileInfoEntity().getCutId()).getCoalPileVariety())) {
            data.put("${10}", "烟煤");
        } else {
            data.put("${10}", this.cutUpService.getCutUpByCutUpId(pdfVo.getCoalPileInfoEntity().getCutId()).getCoalPileVariety());
        }
        String png = null;
        if (pdfVo.getCoalPileInfoEntity().getName().equals(pdfVo.getMeiName())) {
            String pngUrl = pdfVo.getCoalPileInfoEntity().getUrlImage1();
            int index = pngUrl.indexOf("_");
            png = this.minioConfig.downloadFile(pngUrl.substring(0, index + 1) + coalYardId + "_open3d.png", "png");
        } else {
            png = this.minioConfig.downloadFile(pdfVo.getCoalPileInfoEntity().getUrlImage1(), "png");
        }
        if (png == null) {
            log.error("生成word时图片下载失败");
            return;
        }
        picData.put("${9}", png);
        SimpleDateFormat DateFormat = new SimpleDateFormat("MM-dd_HH-mm");
        String datetimeFileName = DateFormat.format(createTime);
        String cutName = this.cutUpService.getCutUpByCutUpId(pdfVo.getCoalPileInfoEntity().getCutId()).getName();
        String wordName = datetimeFileName + "_" + cutName + ".docx";
        operateWord(data, picData, wordName, response);
        System.out.println();
    }

    public static void operateWord(Map<String, Object> data, Map<String, Object> picData, String wordName, HttpServletResponse response) {
        try {
            ClassPathResource resource = new ClassPathResource("template/常州.docx");
            InputStream is = resource.getInputStream();
            XWPFDocument document = new XWPFDocument(is);
            if (data.size() > 0) {
                WordUtils.changeText(document, data);
                WordUtils.changeTableText(document, data);
            }
            if (picData.size() > 0) {
                WordUtils.changePic(document, picData);
                WordUtils.changeTablePic(document, picData);
            }

            FileOutputStream out = new FileOutputStream("D:\\coal\\pdf\\" + wordName);
            document.write(out);
            String encodedFileName = URLEncoder.encode(wordName, "UTF-8");
            String headerValue = "attachment; filename=\"" + encodedFileName + "\"";
            response.setHeader("Content-Disposition", headerValue);
            ServletOutputStream servletOutputStream = response.getOutputStream();
            document.write((OutputStream) servletOutputStream);
            servletOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void fillData(AcroFields fields, Map<String, String> data) {
        try {
            for (String key : data.keySet()) {
                String value = data.get(key);
                fields.setField(key, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @ApiOperation("生成Excels(直接下载到浏览器)")
    @GetMapping({"/excels_2"})
    public void excels_2(@RequestParam("CoalYardId") Integer CoalYardId, @RequestParam("historyId") Integer historyId, HttpServletResponse response) {
        List<CoalPileInfoVo> pdfVo1 = this.coalPileInfoService.getALLByHistoryId(historyId);
        BufferedImage bufferImg = null;
        System.err.println(pdfVo1);
        FileInputStream fs = null;
        try {
            fs = new FileInputStream("./xmsy.xlsx");
            XSSFWorkbook wb = new XSSFWorkbook(fs);
            XSSFSheet sheet = wb.getSheetAt(0);
            FileOutputStream out = new FileOutputStream("./xmsy2.xlsx");
            sheet.createFreezePane(2, 0, 2, 0);
            CoalYardInfoEntity byId = (CoalYardInfoEntity) this.coalYardInfoService.getById(CoalYardId);
            CoalPileInfoEntity name = (CoalPileInfoEntity) this.coalPileInfoService.getOne((Wrapper) ((QueryWrapper) ((QueryWrapper) (new QueryWrapper()).eq("name", byId.getName())).orderBy(true, false, (Object[]) new String[]{"create_time"})).last("limit 0,1"));
            Double dowmcoal_volume = byId.getBottomVolume();
            Double dowmcoal_density = byId.getBottomDensity();
            for (int i = pdfVo1.size() - 1; i >= 0; i--) {
                CutUpEntity cutUpEntity = (CutUpEntity) this.cutUpService.getById(((CoalPileInfoVo) pdfVo1.get(i)).getCutId());
                sheet.shiftRows(2, sheet.getLastRowNum(), 1);
                sheet.createRow(2);
                XSSFRow row = sheet.getRow(2);
                row.createCell(0).setCellValue(((CoalPileInfoVo) pdfVo1.get(i)).getName());
                row.createCell(1).setCellValue(((CoalPileInfoVo) pdfVo1.get(i)).getHeight().doubleValue());
                row.createCell(2).setCellValue(((CoalPileInfoVo) pdfVo1.get(i)).getVolume().doubleValue());
                row.createCell(3).setCellValue(((CoalPileInfoVo) pdfVo1.get(i)).getDensity().doubleValue());
                row.createCell(4).setCellValue(((CoalPileInfoVo) pdfVo1.get(i)).getWeight().doubleValue());
                if (cutUpEntity.getCutType().intValue() == 1) {
                    if (((CoalPileInfoVo) pdfVo1.get(i)).getName().equals(byId.getName())) {
                        row.createCell(5).setCellValue(dowmcoal_volume.doubleValue());
                        row.createCell(6).setCellValue(dowmcoal_density.doubleValue());
                        row.createCell(7).setCellValue(dowmcoal_volume.doubleValue() * dowmcoal_density.doubleValue());
                        row.createCell(8).setCellValue(((CoalPileInfoVo) pdfVo1.get(i)).getWeight().doubleValue() + dowmcoal_volume.doubleValue() * dowmcoal_density.doubleValue());
                    } else {
                        double pileVolume = Double.parseDouble(String.valueOf(Math.abs(cutUpEntity.getXa1().intValue() - cutUpEntity.getXa2().intValue()) / 360.0D * dowmcoal_volume.doubleValue()));
                        row.createCell(5).setCellValue(pileVolume);
                        row.createCell(6).setCellValue(dowmcoal_density.doubleValue());
                        row.createCell(7).setCellValue(pileVolume * dowmcoal_density.doubleValue());
                        row.createCell(8).setCellValue(((CoalPileInfoVo) pdfVo1.get(i)).getWeight().doubleValue() + pileVolume * dowmcoal_density.doubleValue());
                    }
                } else {
                    row.createCell(8).setCellValue(((CoalPileInfoVo) pdfVo1.get(i)).getWeight().doubleValue());
                }
            }
            String s = null;
            if (ObjectUtil.isNull(name)) {
                s = ((CoalPileInfoVo) pdfVo1.get(0)).getUrlImage2();
            } else {
                s = name.getUrlImage2();
            }
            String newFilename = "test.jpg";
            newFilename = new String(newFilename.getBytes(), "iso8859-1");
            String s3 = s;
            System.out.println(s3);
            URL ur = new URL(s3);
            InputStream imput = ur.openStream();
            int firstByte = imput.read();
            if (firstByte != -1) {
                System.out.println("流不为空，有数据");
            } else {
                System.out.println("流为空，没有数据");
                RRException rRException = new RRException("图片不存在");
            }
            FileOutputStream write = new FileOutputStream("./Excel.jpg");
            byte[] b = new byte[1024];
            int k = 0;
            sheet.createRow(15);
            XSSFRow row1 = sheet.getRow(15);
            while ((k = imput.read(b)) != -1) {
                write.write(b, 0, k);
                write.flush();
            }
            ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
            bufferImg = ImageIO.read(new File("./Excel.jpg"));
            ImageIO.write(bufferImg, "png", byteArrayOut);
            XSSFDrawing drawingPatriarch = sheet.createDrawingPatriarch();
            XSSFClientAnchor xssfClientAnchor = new XSSFClientAnchor(0, 0, 255, 255, 1, pdfVo1.size() + 5, 8, pdfVo1.size() + 18);
            xssfClientAnchor.setAnchorType(ClientAnchor.AnchorType.byId(3));
            drawingPatriarch.createPicture(xssfClientAnchor, wb.addPicture(byteArrayOut.toByteArray(), 6));
            out.flush();
            response.reset();
            response.setContentType("application/octet-stream; charset=utf-8");
            response.setHeader("content-Disposition", "attachment;filename=" + newFilename + ".xlsx");
            response.getOutputStream().flush();
            wb.write((OutputStream) response.getOutputStream());
            response.getOutputStream().close();
            wb.write(out);
            imput.close();
            write.close();
            out.close();
            fs.close();
            wb.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

